import kotlinx.coroutines.*
import kotlin.system.measureTimeMillis

fun main() = runBlocking {
    // 1. 基本协程示例
    println("===== 基本协程示例 =====")
    launch {
        delay(1000L)
        println("协程执行完成! (${Thread.currentThread().name})")
    }
    println("主线程继续执行... (${Thread.currentThread().name})")

    delay(1200L) // 等待协程完成

    // 2. 结构化并发示例
    println("\n===== 结构化并发示例 =====")
    val job = launch {
        repeat(5) { i ->
            println("任务 $i 执行中... (${Thread.currentThread().name})")
            delay(500L)
        }
    }
    delay(1500L) // 等待部分执行
    println("取消剩余任务")
    job.cancel() // 取消协程
    job.join()   // 等待取消完成
    println("任务已取消")

    // 3. 异步返回值示例
    println("\n===== 异步返回值示例 =====")
    val time = measureTimeMillis {
        val result1 = async { fetchData(1, 1000L) }
        val result2 = async { fetchData(2, 800L) }

        println("结果: ${result1.await()} + ${result2.await()} = ${result1.await() + result2.await()}")
    }
    println("总耗时: ${time}ms")

    // 4. 协程上下文切换示例
    println("\n===== 上下文切换示例 =====")
    withContext(Dispatchers.Default) {
        println("CPU密集型任务 (${Thread.currentThread().name})")
        // 模拟CPU密集型计算
        var sum = 0
        for (i in 1..1_000_000) {
            sum += i
        }
        println("计算结果: $sum")
    }

    // 5. 异常处理示例
    println("\n===== 异常处理示例 =====")
    val handler = CoroutineExceptionHandler { _, exception ->
        println("捕获异常: $exception")
    }

    val scope = CoroutineScope(Job() + Dispatchers.IO + handler)
    scope.launch {
        try {
            delay(100L)
            throw RuntimeException("测试异常")
        } catch (e: Exception) {
            println("内部捕获: ${e.message}")
        }

        // 不会被取消的协程
        launch(NonCancellable) {
            delay(200L)
            println("清理任务完成")
        }
    }

    delay(1000L) // 等待所有任务完成
    println("\n===== 所有示例完成 =====")
}

// 模拟网络请求
suspend fun fetchData(id: Int, delay: Long): Int {
    delay(delay)
    println("请求 $id 完成 (${Thread.currentThread().name})")
    return id * 10
}